#ifndef SERVICEMANAGER_H
#define SERVICEMANAGER_H

#include "./entities/messageentities.h"

class ServiceManager: public QObject
{
    Q_OBJECT
public:
    static ServiceManager& getInstance();

    ServiceManager(ServiceManager&) = delete;
    ServiceManager& operator=(const ServiceManager&) = delete;


public slots:
    /* 接受来自UI线程的信号 */
    // 服务器准备下线，修改全部用户在线状态
    void logoutAllUsersNow();

    /* 接受来自Handler线程的信号 */
    // 登录检查
    void loginCheck(const qintptr descriptor, const LoginRequestMessage);
    // 注册新用户
    void registerNewUser(const qintptr descriptor, const RegisterRequestMessage);
    // 登出
    void logout(const qintptr descriptor, const LogoutRequestMessage);
    // 搜索新用户
    void searchNewUser(const qintptr descriptor, const SearchUserRequestMessage);
    // 添加好友申请到缓存列表
    void addFriendshipVerifyInfo(const qintptr descriptor, const ApplyFriendRequestMessageToServer);
    // 改变好友的状态（对方通过或拒绝好友申请）
    void changeFriendshipStatus(const qintptr descriptor, const ApplyFriendResponseMessageToServer);
    // 用户刚刚上线请求查看自己的数据缓存
    void checkDataBuffer(const qintptr descriptor, const RequestBufferDataMessage);
    // 改变好友申请状态（申请转发给客户端后status从0变1）
    void changeFriendApplicationStatus(const qintptr descriptor, const GetApplicationFromServer);
    // 改变好友申请结果的发送状态（审核结果转发给客户端后status从2或3变成4）
    void changeFriendApplicationResultSendStatus(const qintptr descriptor, const GetApplicationResultFromServer);
    // 收到用户发给其好友的聊天消息
    void saveChatMessage(const qintptr descriptor, const ChatMessageToServer);
    // 改变好友消息的状态（消息缓存从0变1以代表接受者收到）
    void changeChatMsgStatus(const qintptr descriptor, const GetChatMessageFromServer);
    // 试图转发客户端发起的视频通话请求
    void transpondVideoRequest(const qintptr descriptor, const VideoRequestToServer);
    // 转发客户端回应的视频通话请求回复
    void transpondVideoResponse(const qintptr descriptor, const VideoResponseToServer);


    /* 接受来自网络收发线程的信号 */
    // 仅仅下线用户，适用于用户没有主动登出，断电式下线
    void onlyLogoutUser(const qintptr descriptor, const QString userId);

signals:
    /* 发给Handler线程 */
    // 返回登录成功与否
    void returnLoginCheckResponse(const qintptr descriptor, const LoginResponseMessage);
    // 返回注册成功与否
    void returnRegisterCheckResponse(const qintptr descriptor, const RegisterResponseMessage);
    // 返回登出成功与否
    void returnLogoutCheckResponse(const qintptr descriptor, const LogoutResponseMessage);
    // 返回用户搜索结果
    void returnSearchUserResponse(const qintptr descriptor, const SearchUserResponseMessage);
    // 某个用户被其他人申请，返回需要转发给这个用户的验证消息
    void returnOthersApplicationMessage(const QString receiverId,
                                        const ApplyFriendRequestMessageToClient);
    // 某个用户申请了其他用户好友，其他用户完成了审核，返回给这个用户审核结果
    void returnFinishedApplicationResultMessage(const QString receiverId,
                                                const ApplyFriendResponseMessageToClient);
    // 其他用户给某个用户发聊天消息，转发给这个用户聊天消息
    void returnOtherChatMsg(const QString receiver, const ChatMessageToClient);
    // 转发给视频通话发起者视频通话结果
    void returnVideoResponseToRequestUser(const QString requestUserId, const VideoResponseToClient);
    // 转发给视频通话接受者视频通话请求
    void returnVideoRequestToResponseUser(const QString responseUserId, const VideoRequestToClient);

    /* 发给网络收发线程 */
    // 告诉网络收发线程哪个用户下线了
    void userIdLogout(const qintptr descriptor, const QString userId);
    // 告诉网络收发线程哪个用户上线了
    void addOnlineUser(const qintptr descriptor, const QString userId);

private:
    static ServiceManager m_instance;

    // 生成加盐哈希中的盐值
    QString generateSalt(int length = 16);
    // 加盐哈希
    QByteArray hashPassword(const QString &password, const QString &salt);

    // 用户登录成功后，检查需要转发给这个家伙的消息
    void checkOthersMessage(const int& userId);

    /* 上面那个函数的子函数 */
    // 检查是否有人申请user为好友
    void checkNewFriendApplication(const int& userId);
    // 检查user向其他人申请的好友申请是否有结果
    void checkFriendApplicationResult(const int& userId);
    // 检查是否有人给user发聊天消息
    void checkNewChatMsg(const int& userId);


    explicit ServiceManager(QObject* parent = nullptr);
    ~ServiceManager();


};

#endif // SERVICEMANAGER_H
